package fr.bordeaux1.planingdesetudiants.view;

import java.io.File;
import java.io.IOException;
import java.sql.SQLException;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.wb.swt.SWTResourceManager;

import fr.bordeaux1.planingdesetudiants.controler.EdtExporter;
import fr.bordeaux1.planingdesetudiants.controler.db.DBOpener;
import fr.bordeaux1.planingdesetudiants.controler.db.IDBPlaningDesEtudiants;
import fr.bordeaux1.planingdesetudiants.model.AccumulateurErreur;

public class MainFrame implements IFenetrePrincipale {

	protected Shell shell;
	private IEdtViewer edtViewer;
	private MenuItem emploisDuTempsMenuItem;
	private IDBPlaningDesEtudiants db;
	private TabFolder tabFolder;
	private CompositeEtu compositeEtu;
	private CompositeEns compositeEns;
	private CompositUes compositeUes;
	private MenuItem affichageMenuItem;
	private MenuItem mntmVrifierLesErreurs;
	private MenuItem mntmExportWeb;
	private Label statusBar;

	/**
	 * Launch the application.
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			MainFrame window = new MainFrame();
			window.open();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Open the window.
	 */
	public void open() {

		Display display = Display.getDefault();
		createContents();
		shell.open();
		shell.layout();
		// createFenetreEdtViewer();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
	}

	private void createFenetreEdtViewer() {
		edtViewer = new EdtViewer2(this);
		// edtViewer.show();
		edtViewer.refreshData();
	}

	/**
	 * Create contents of the window.
	 */
	protected void createContents() {
		shell = new Shell();
		shell.setMinimumSize(new Point(964, 580));

		shell.setImage(SWTResourceManager
				.getImage(MainFrame.class, "/icon.png"));
		shell.setSize(964, 580);
		shell.setText("Planning des étudiants");
		shell.setLayout(new FormLayout());

		Menu menu = new Menu(shell, SWT.BAR);
		shell.setMenuBar(menu);

		MenuItem fichierSubmenu = new MenuItem(menu, SWT.CASCADE);
		fichierSubmenu.setText("Fichier");

		Menu fichierMenu = new Menu(fichierSubmenu);
		fichierSubmenu.setMenu(fichierMenu);
		MenuItem ouvrirEdtMenuItem = new MenuItem(fichierMenu, SWT.NONE);
		ouvrirEdtMenuItem.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent arg0) {
				ouvrirEdt();
			}
		});
		ouvrirEdtMenuItem.setText("Ouvrir un emploi du temps existant...");

		new MenuItem(fichierMenu, SWT.SEPARATOR);

		MenuItem nouveauEdtXmlMenuItem = new MenuItem(fichierMenu, SWT.NONE);
		nouveauEdtXmlMenuItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				nouveauEdtXml();
			}
		});

		MenuItem nouveauEdtTexMenuItem = new MenuItem(fichierMenu, SWT.NONE);
		nouveauEdtTexMenuItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				nouveauEdtTex();
			}
		});

		nouveauEdtTexMenuItem
				.setText("Nouvel emploi du temps depuis un fichier TEX...");

		nouveauEdtXmlMenuItem
				.setText("Nouvel emploi du temps depuis un fichier XML...");

		new MenuItem(fichierMenu, SWT.SEPARATOR);

		MenuItem quitterMenuItem = new MenuItem(fichierMenu, SWT.NONE);
		quitterMenuItem.setText("Quitter");
		quitterMenuItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				shell.dispose();
			}
		});

		MenuItem outilsMenu = new MenuItem(menu, SWT.CASCADE);
		outilsMenu.setText("Outils");

		Menu menu_1 = new Menu(outilsMenu);
		outilsMenu.setMenu(menu_1);

		mntmVrifierLesErreurs = new MenuItem(menu_1, SWT.NONE);
		mntmVrifierLesErreurs.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				if (db != null) {
					try {
						AccumulateurErreur accumulateur = db
								.rechercherErreurs();
						DetailDesErreursDialog dialog = new DetailDesErreursDialog(
								shell, accumulateur);
						dialog.open();
					} catch (SQLException e) {
						e.printStackTrace();
					}
					updateStatusBar("Erreurs vérifiées");
				}
			}
		});
		mntmVrifierLesErreurs.setText("Vérifier les erreurs maintenant");
		mntmVrifierLesErreurs.setEnabled(false);

		mntmExportWeb = new MenuItem(menu_1, SWT.NONE);
		mntmExportWeb.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				exportWeb();
			}
		});
		mntmExportWeb.setText("Exporter au format WEB");
		mntmExportWeb.setEnabled(false);

		affichageMenuItem = new MenuItem(menu, SWT.CASCADE);
		affichageMenuItem.setText("Affichage");

		Menu affichageMenu = new Menu(affichageMenuItem);
		affichageMenuItem.setMenu(affichageMenu);

		emploisDuTempsMenuItem = new MenuItem(affichageMenu, SWT.CHECK);
		emploisDuTempsMenuItem.setSelection(false);
		emploisDuTempsMenuItem.setText("Emploi du temps");
		emploisDuTempsMenuItem.setEnabled(false);

		MenuItem aideSubMenu = new MenuItem(menu, SWT.CASCADE);
		aideSubMenu.setText("?");

		Menu aideMenu = new Menu(aideSubMenu);
		aideSubMenu.setMenu(aideMenu);

		MenuItem aProposMenuItem = new MenuItem(aideMenu, SWT.NONE);
		aProposMenuItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				AboutDialog aboutDialog = new AboutDialog(shell);
				aboutDialog.create();
				aboutDialog.open();
			}
		});
		aProposMenuItem.setText("À Propos");

		statusBar = new Label(shell, SWT.BORDER | SWT.RIGHT | SWT.SHADOW_IN);
		FormData fd_statusBar = new FormData();
		fd_statusBar.right = new FormAttachment(100);
		fd_statusBar.left = new FormAttachment(0);
		fd_statusBar.bottom = new FormAttachment(100);
		statusBar.setLayoutData(fd_statusBar);

	}

	protected void exportWeb() {
		String rep = selectRepWeb();
		EdtExporter export = new EdtExporter(db, rep);
		try {
			export.doExport();
		} catch (Exception e) {
			e.printStackTrace();
		}
		updateStatusBar("Emploi du temps exporté au format html");
	}

	private String selectRepWeb() {
		DirectoryDialog dialog = new DirectoryDialog(shell, SWT.OPEN);
		dialog.setFilterPath(System.getProperty("user.home"));
		dialog.setText("Sélectionner le répertoire d'exportation");
		dialog.open();
		return dialog.getFilterPath() + File.separator;
	}

	private void creerOnglets() {
		tabFolder = new TabFolder(shell, SWT.NONE);
		FormData fd_tabFolder = new FormData();
		fd_tabFolder.top = new FormAttachment(0);
		fd_tabFolder.left = new FormAttachment(0);
		fd_tabFolder.bottom = new FormAttachment(statusBar);
		fd_tabFolder.right = new FormAttachment(100);
		tabFolder.setLayoutData(fd_tabFolder);
		tabFolder.setVisible(true);
		tabFolder.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				updateStatusBar("");
			}
		});
		
		TabItem etudiantsTab = new TabItem(tabFolder, SWT.NONE);
		etudiantsTab.setText("Etudiants");

		TabItem uesTab = new TabItem(tabFolder, SWT.NONE);
		uesTab.setText("UEs");

		TabItem enseignantsTab = new TabItem(tabFolder, SWT.NONE);
		enseignantsTab.setText("Enseignants");

		compositeEns = new CompositeEns(tabFolder, SWT.NONE, this);
		compositeUes = new CompositUes(tabFolder, SWT.NONE, this);
		compositeEtu = new CompositeEtu(tabFolder, SWT.NONE, this);

		mntmVrifierLesErreurs.setEnabled(true);
		mntmExportWeb.setEnabled(true);
		affichageMenuItem.setEnabled(true);
		emploisDuTempsMenuItem.setEnabled(true);
		emploisDuTempsMenuItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent selectionEvent) {
				boolean display = ((MenuItem) selectionEvent.getSource())
						.getSelection();
				if (display) {
					if (edtViewer != null)
						edtViewer.show();
					else {
						createFenetreEdtViewer();
						edtViewer.show();
					}
				} else {
					edtViewer.close();
				}
			}
		});
		enseignantsTab.setControl(compositeEns);
		uesTab.setControl(compositeUes);
		etudiantsTab.setControl(compositeEtu);
		tabFolder.addSelectionListener(new SelectionListener() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				((IOnglet) (((TabItem) arg0.item).getControl())).refreshData();
			}

			@Override
			public void widgetDefaultSelected(SelectionEvent arg0) {

			}
		});
		shell.layout();
	}

	private String selectXml() {
		FileDialog dialog = new FileDialog(shell, SWT.OPEN);
		String[] extensions = { "*.xml" };
		String[] nomextensions = { "Fichiers XML" };
		dialog.setFilterNames(nomextensions);
		dialog.setFilterExtensions(extensions);
		dialog.setFilterPath(System.getProperty("user.home"));
		dialog.setText("Sélectionner un fichier XML contenant les étudiants et les UEs");
		dialog.open();
		return dialog.getFilterPath() + File.separator + dialog.getFileName();
	}

	private String selectTex() {
		FileDialog dialog = new FileDialog(shell, SWT.OPEN);
		String[] extensions = { "*.tex" };
		String[] nomextensions = { "Fichiers TEX" };
		dialog.setFilterNames(nomextensions);
		dialog.setFilterExtensions(extensions);
		dialog.setFilterPath(System.getProperty("user.home"));
		dialog.setText("Sélectionner un fichier TEX contenant les étudiants et les UEs");
		dialog.open();
		return dialog.getFilterPath() + File.separator + dialog.getFileName();
	}

	private String selectDb(boolean creation) {
		FileDialog dialog = new FileDialog(shell, creation ? SWT.SAVE
				: SWT.OPEN);
		String[] extensions = { "*.edt" };
		String[] nomextensions = { "Fichiers d'emplois du temps" };
		dialog.setFilterNames(nomextensions);
		dialog.setFilterExtensions(extensions);
		dialog.setFilterPath(System.getProperty("user.home"));
		if (creation)
			dialog.setText("Selectionner le fichier d'enregistrement de l'emploi du temps");
		else
			dialog.setText("Sélectionner un fichier d'emploi du temps précédement créé");

		String filename = dialog.open();

		if (creation && filename != null) {
			File f = new File(filename);
			if (f.exists()) {
				String[] boutons = { "Valider", "Annuler" };
				new MessageDialog(getShell(), "Attention", null,
						"Le fichier existe déjà, voulez-vous l'écraser?", 0,
						boutons, 0);
				boolean quest = MessageDialog.openQuestion(getShell(),
						"Attention",
						"Le fichier existe déjà, voulez-vous l'écraser?");
				if (quest) {
					f.delete();
					try {
						f.createNewFile();
					} catch (IOException e) {
						e.printStackTrace();
					}
					return filename;
				} else {
					return selectDb(creation);
				}
			}
		}
		return filename;
	}

	protected void nouveauEdtTex() {
		String tex = selectTex();
		System.out.println("addr:" + tex);
		String dbFile = null;
		if (tex != null)
			dbFile = selectDb(true);

		if (dbFile != null && tex != null) {
			try {
				db = DBOpener.createFromTex(dbFile, tex);
				creerOnglets();
				modificationApportees();
				updateStatusBar("Nouveau projet d'emploi du temps créé avec succès");
			} catch (Exception e) {
				e.printStackTrace();
				MessageBox box = new MessageBox(shell, SWT.ERROR);
				box.setText("La création a échoué !");
				box.setMessage(e.getLocalizedMessage());
				box.open();
			}
		}
		
	}

	protected void nouveauEdtXml() {
		String xml = selectXml();
		System.out.println("addr:" + xml);
		String dbFile = null;
		if (xml != null)
			dbFile = selectDb(true);

		System.out.println(dbFile);
		if (dbFile != null && xml != null) {
			try {
				db = DBOpener.createFromXml(dbFile, xml);
				creerOnglets();
				modificationApportees();
				updateStatusBar("Nouveau projet d'emploi du temps créé avec succès");
			} catch (Exception e) {
				MessageBox box = new MessageBox(shell, SWT.ERROR);
				box.setText("La création a échoué !");
				box.setMessage(e.getLocalizedMessage());
				box.open();
			}
		}
	}

	protected void ouvrirEdt() {
		String dbfile = selectDb(false);
		if (dbfile != null) {
			try {
				db = DBOpener.open(dbfile);
				creerOnglets();
				modificationApportees();
				updateStatusBar("Projet d'emploi du temps ouvert avec succès");
			} catch (Exception e) {
				MessageBox box = new MessageBox(shell, SWT.ERROR);
				box.setText("L'ouverture a échoué !");
				box.setMessage(e.getLocalizedMessage());
				box.open();
			}
		}
	}

	@Override
	public Shell getShell() {
		return this.shell;
	}

	@Override
	public void edtClosed() {
		edtViewer = null;
		emploisDuTempsMenuItem.setSelection(false);
	}

	@Override
	public IDBPlaningDesEtudiants getDb() {
		return db;
	}

	@Override
	public void modificationApportees() {
		compositeEns.refreshData();
		compositeEtu.refreshData();
		compositeUes.refreshData();
		if (edtViewer != null)
			edtViewer.refreshData();

	}

	public void updateStatusBar(String news) {
		statusBar.setText(news);
		statusBar.update();
		shell.layout();
	}
}
